package com.jdcjk.project.car.view.gaode;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.support.design.widget.FloatingActionButton;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.AMapUtils;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.SupportMapFragment;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.maps.model.animation.Animation;
import com.amap.api.maps.model.animation.TranslateAnimation;
import com.amap.api.trace.LBSTraceClient;
import com.amap.api.trace.TraceListener;
import com.amap.api.trace.TraceLocation;
import com.jdcjk.Constant;
import com.jdcjk.R;
import com.jdcjk.UrlAddress;
import com.jdcjk.base.presenter.BasePresenter;
import com.jdcjk.base.view.BaseFragment;
import com.jdcjk.chat.OpenFireConnectionManager;
import com.jdcjk.chat.enity.MessageBean;
import com.jdcjk.project.car.model.entity.LocationReplayResult;
import com.jdcjk.project.car.model.entity.TerminalInfoResult;
import com.jdcjk.project.car.model.entity.TerminalPathBean;
import com.jdcjk.project.car.presenter.CarPresenter;
import com.jdcjk.project.car.view.TerminalDetailsActivity;
import com.jdcjk.project.main.model.entity.CarListInfo;
import com.jdcjk.util.GaoDeMapUtil;
import com.jdcjk.util.TimeUtils;
import com.jdcjk.view.LoadingDialog;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import okhttp3.Call;
import okhttp3.Request;

/**
 * Created by dong on 2016/12/13.
 * 实时追踪和轨迹回放
 */
@SuppressLint({"NewApi", "ValidFragment"})
public class GaoDeRealTrackFragment extends BaseFragment<CarPresenter> implements AMap.InfoWindowAdapter, SeekBar.OnSeekBarChangeListener, LocationSource, AMapLocationListener {
    private final String TAG = GaoDeRealTrackFragment.class.getSimpleName();
    private CarPresenter carPresenter;
    private AMap aMap = null;
    //顶栏标题TextView
    private TextView barTitle_textview;
    //车辆信息实体类
    private CarListInfo carListInfo;
    //车辆id
    private int terminalId;
    //是否点开车辆信息窗口
    private boolean isOpenCarWindow = false;
    //车辆标志物
    private Marker carMarker;

    public static final int REAL_TIME_TTACK = 1;
    public static final int TRACK_PLAY_BACK = 2;
    //显示区域设置
    private CameraPosition cameraPosition;
    //是否在回放
    public boolean isPlayBack = false;
    private int fragmentType;
    //车辆位置信息
    private LatLng carLatLng;
    //缩放等级
    private float zoomLevel = 14;
    //加载弹窗
    private LoadingDialog loadingDialog;
    //车辆是否是高精度类型
    private boolean isHighPrecision = false;

    //车辆方向
    private float carDirection;

    private Handler handler = new Handler();

    public GaoDeRealTrackFragment(int fragmentType) {
        this.fragmentType = fragmentType;
    }

    @Override
    public int getLayoutId() {
        return R.layout.fragment_real_track_gaode;
    }

    @Override
    public CarPresenter bindPresenter() {
        carPresenter = new CarPresenter(getContext());
        return carPresenter;
    }

    @Override
    public void initContentView(View viewContent) {
        //实时追踪对象绑定
        realTimeTrackBar_rl = (RelativeLayout) viewContent.findViewById(R.id.real_time_track_bar_rl);
        refresh_button = (ImageButton) viewContent.findViewById(R.id.real_time_refresh_btn);
        refresh_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                initCar();
                //判断与openFire是否断开，断开则重连
                if (OpenFireConnectionManager.getInstance().getXMPPTcpConnection() != null && OpenFireConnectionManager.getInstance().getXMPPTcpConnection().isAuthenticated()) {
                    return;
                } else {
                    OpenFireConnectionManager.getInstance().getXMPPTcpConnection();
                    OpenFireConnectionManager.getInstance().connect();
                }
                //如果没开启实时追踪，则开启
                if (!isRealTimeTrack) {
                    isRealTimeTrack = true;
                }
            }
        });
        mapType_button = (ImageButton) viewContent.findViewById(R.id.fragment_real_time_map_type_btn);
        mapType_button.setOnClickListener(this);
        traffic_button = (ImageButton) viewContent.findViewById(R.id.fragment_real_time_traffic_btn);
        traffic_button.setOnClickListener(this);
        carNaviFind_button = (ImageButton) viewContent.findViewById(R.id.car_navi_find_btn);
        carNaviFind_button.setOnClickListener(this);
        changePosition_button = (ImageButton) viewContent.findViewById(R.id.change_position_btn);
        changePosition_button.setOnClickListener(this);
        barTitle_textview = (TextView) viewContent.findViewById(R.id.bar_title_tv);
        polylineOptions = (new PolylineOptions())
                .color(Color.rgb(9, 129, 240)).width(4.0f);
        //轨迹回放对象绑定
        playBackBar_ll = (LinearLayout) viewContent.findViewById(R.id.play_back_bar_ll);
        playBack_seekBar = (SeekBar) viewContent.findViewById(R.id.play_back_seekBar);
        playBack_button = (Button) viewContent.findViewById(R.id.play_back_btn);
        playBack_button.setOnClickListener(this);
        playBack_seekBar.setOnSeekBarChangeListener(this);
        timeChoice_button = (ImageButton) viewContent.findViewById(R.id.time_choice_btn);
        timeChoice_button.setOnClickListener(this);
        carSpeed_textview = (TextView) viewContent.findViewById(R.id.car_speed_tv);
        carLocationTime_textview = (TextView) viewContent.findViewById(R.id.car_location_time_tv);
        carLatitude_textview = (TextView) viewContent.findViewById(R.id.car_latitude);
        carLongitude_textview = (TextView) viewContent.findViewById(R.id.car_longitude_tv);
        placBackProgress_textview = (TextView) viewContent.findViewById(R.id.plac_back_progress_tv);
        trajectoryCorrection_button = (FloatingActionButton) viewContent.findViewById(R.id.trajectory_correction_btn);
        trajectoryCorrection_button.setOnClickListener(this);
        //初始化加载dialog
        loadingDialog = new LoadingDialog(getActivity(), R.style.dialogTheme);

        viewContent.findViewById(R.id.back_btn).setOnClickListener(this);
        initMap();

    }

    @Override
    public void initData() {
        super.initData();
        Bundle bundle = getArguments();//从activity传过来的Bundle
        //获取设备Id
        terminalId = bundle.getInt(Constant.TerminalInfo.terminalId);
        initView();
    }

    //初始化控件(根据显示的fragmentType来显示，屏蔽相应的功能)
    private void initView() {
        aMap.clear();
        if (fragmentType == REAL_TIME_TTACK) {
            //如果为实时追踪fragment
            //显示标题修改
            barTitle_textview.setText(R.string.real_time_track);
            realTimeTrackBar_rl.setVisibility(View.VISIBLE);
            refresh_button.setVisibility(View.VISIBLE);
            playBackBar_ll.setVisibility(View.GONE);
            timeChoice_button.setVisibility(View.GONE);
            trajectoryCorrection_button.setVisibility(View.GONE);
            // 此方法为每隔固定时间会发起一次定位请求，为了减少电量消耗或网络流量消耗，
            // 注意设置合适的定位时间的间隔（最小间隔支持为2000ms），并且在合适时间调用stopLocation()方法来取消定位请求
            // 在定位结束后，在合适的生命周期调用onDestroy()方法
            // 在单次定位情况下，定位无论成功与否，都无需调用stopLocation()方法移除请求，定位sdk内部会移除
            mlocationClient.startLocation();//启动定位
            //如果之前未加载过车辆位置信息，则加载
            if (carListInfo == null) {
                initCar();
            } else {
                addCarMarker(carLatLng, carListInfo.getOnline(), carListInfo.getDirection());
                carMarker.showInfoWindow();
                //如果此时个人定位已经确定，则重新计算缩放等级
                if (personalLatLng != null) {
                    float distance = AMapUtils.calculateLineDistance(carLatLng, personalLatLng);
                    //根据车与人的距离设定缩放大小
                    zoomLevel = GaoDeMapUtil.getZoomLevelByDistance(distance);
                    //设定地图缩放等级
                    aMap.moveCamera(CameraUpdateFactory.zoomTo(zoomLevel));
                }
                //移动到车辆位置
                animateToLocation(carLatLng);
                isCarPosition = true;
                changePosition_button.setSelected(isCarPosition);
            }
            //默认开启实时追踪
            isRealTimeTrack = true;
        } else {
            //如果为轨迹回放fragment
            //显示标题修改
            barTitle_textview.setText(R.string.track_play_back);
            playBackBar_ll.setVisibility(View.VISIBLE);
            realTimeTrackBar_rl.setVisibility(View.GONE);
            refresh_button.setVisibility(View.GONE);
            trajectoryCorrection_button.setVisibility(View.VISIBLE);
            //初始化显示文本
            playBack_button.setText(R.string.play_back);
            carSpeed_textview.setText(R.string.speed);
            carLatitude_textview.setText(R.string.latitude);
            carLongitude_textview.setText(R.string.longitude);
            carLocationTime_textview.setText(R.string.location_time);
            aMap.setMapType(AMap.MAP_TYPE_NORMAL);
            //清除之前的轨迹
            terminalPathList = new ArrayList<>();
            aMap.clear();
            //时间选择按钮显示
            timeChoice_button.setVisibility(View.VISIBLE);
//            initCar();
            //移动到已经存在的车辆位置
            if (carListInfo != null) {
                carLatLng = new LatLng(carListInfo.getLatitude(), carListInfo.getLongitude());
                addCarMarker(carLatLng, carListInfo.getOnline(), carListInfo.getDirection());
                //移动到车辆位置
                animateToLocation(carLatLng);
            }
            mlocationClient.stopLocation();//取消定位服务
            //默认没有回放轨迹
            refreshPlayBackPath(new ArrayList<TerminalPathBean>());
        }
    }

    /**
     * 切换fragment类型显示（实时追踪1/轨迹回放2）
     *
     * @param fragmentType
     */
    public void changeFragmentType(int fragmentType) {
        this.fragmentType = fragmentType;
        //如果正在回放则停止回放
        if (isPlayBack) {
            handler.removeCallbacks(playBackRunable);
            playBack_seekBar.setProgress(0);
            playBack_seekBar.setMax(0);
            //获取路径第一个坐标
            LatLng latlng = new LatLng(terminalPathList.get(0).getLatitude(), terminalPathList.get(0).getLongitude());
            addCarMarker(latlng, true, terminalPathList.get(0).getDirection());
            isPlayBack = false;
        }
        //如果正在实时追踪则停止
        if (isRealTimeTrack) {
            isRealTimeTrack = false;
        }
        initView();
    }

    //初始化地图
    private void initMap() {
        //初始化地图变量
        if (aMap == null) {
            aMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.fragment_car_real_time)).getMap();
        }
        // 设置自定义窗口
        aMap.setInfoWindowAdapter(this);
        // 获取Ui设定
        UiSettings mUiSettings = aMap.getUiSettings();
        // 设置显示缩放控件
        mUiSettings.setScaleControlsEnabled(true);
        // 设置不显示指南针控件
        mUiSettings.setCompassEnabled(false);
        // 设置所有手势可用
        mUiSettings.setAllGesturesEnabled(true);
        //设置地图定位
        initLocation();
        //设定地图缩放等级
        aMap.moveCamera(CameraUpdateFactory.zoomTo(zoomLevel));
        //标志物点击监听
        aMap.setOnMarkerClickListener(new AMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                if (!isOpenCarWindow) {
                    if (marker.isInfoWindowShown()) {
                        marker.hideInfoWindow();
                    } else if (fragmentType == REAL_TIME_TTACK) {
                        //如果是实时追踪界面才能显示窗口
                        marker.showInfoWindow();
                    }
                }
                return true;
            }
        });
        //定义了当可视范围改变时回调的接口。
        aMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
            @Override
            public void onCameraChange(CameraPosition cameraPosition) {
                //在可视范围改变完成之后回调此方法。
                zoomLevel = cameraPosition.zoom;
            }

            @Override
            public void onCameraChangeFinish(CameraPosition cameraPosition) {
                //在可视范围一系列动作改变完成之后（例如拖动、fling、缩放）回调此方法。
            }
        });
    }


    //获得地图视图控制
    public AMap getAMap() {
        return aMap;
    }

    //获得切换地图按钮对象
    public ImageView getMapTypeImageView() {
        return mapType_button;
    }

    //初始化车辆位置
    public void initCar() {
        //获得终端信息
        carPresenter.getTerminal(UrlAddress.GET_TERMINAL, String.valueOf(terminalId), new BasePresenter.OnUIThreadListener<TerminalInfoResult>() {
            @Override
            public void onBefore(Request request, int id) {
                loadingDialog.show();
                loadingDialog.setTextView(R.string.is_loaction);
            }

            @Override
            public void onAfter(int id) {

            }

            @Override
            public void onError(Call call, Exception e, int i) {
                loadingDialog.dismiss();
                Toast.makeText(getActivity(), R.string.system_exception, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onResponse(TerminalInfoResult result) {
                switch (result.getStatus()) {
                    case "OK":
                        carListInfo = result.getResult();
                        isHighPrecision = carListInfo.getTerminalType().equals("GJD");
                        carLatLng = new LatLng(carListInfo.getLatitude(), carListInfo.getLongitude());
                        //转换坐标形式
                        carLatLng = GaoDeMapUtil.gaodeLatLngEncrypt(carLatLng);
                        //修改请求返回bean的对应坐标值
                        carListInfo.setLatLng(carLatLng.latitude, carLatLng.longitude);
                        addCarMarker(carLatLng, carListInfo.getOnline(), carListInfo.getDirection());
                        carMarker.showInfoWindow();
                        //如果此时个人定位已经确定，则重新计算缩放等级
                        if (personalLatLng != null) {
                            float distance = AMapUtils.calculateLineDistance(carLatLng, personalLatLng);
                            //根据车与人的距离设定缩放大小
                            zoomLevel = GaoDeMapUtil.getZoomLevelByDistance(distance);
                            //设定地图缩放等级
                            aMap.moveCamera(CameraUpdateFactory.zoomTo(zoomLevel));
                        }
                        //移动到车辆位置
                        animateToLocation(carLatLng);
                        isCarPosition = true;
                        changePosition_button.setSelected(isCarPosition);
                        break;
                    case "FAILED":
                        Toast.makeText(getActivity(), result.getMessage(), Toast.LENGTH_SHORT).show();
                        break;
                }
                loadingDialog.dismiss();
            }
        });
    }

    public CarListInfo getCarListInfo() {
        return carListInfo;
    }

    public void updataCarListInfo(String displayid, String carId, String cardNum) {
        carListInfo.setDisplayid(displayid);
        carListInfo.setCarId(carId);
        carListInfo.setCardNum(cardNum);
    }

    /**
     * 更新显示为设备关闭
     */
    public void closeTermianl() {
        carListInfo.setOnline(false);
        carListInfo.setAcc(false);
        carLatLng = new LatLng(carListInfo.getLatitude(), carListInfo.getLongitude());
        addCarMarker(carLatLng, carListInfo.getOnline());
        //移动到车辆位置
        animateToLocation(carLatLng);
        carMarker.showInfoWindow();
    }

    /**
     * 将中心移动到对应坐标
     *
     * @param latLng 坐标信息
     */
    public void animateToLocation(LatLng latLng) {
        aMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition.fromLatLngZoom(latLng, zoomLevel)));
    }

    /**
     * 在对应位置添加车辆标志物
     *
     * @param latLng   位置信息
     * @param isOnline 车辆是否在线
     * @return
     */
    private Marker addCarMarker(LatLng latLng, boolean isOnline) {
        return addCarMarker(latLng, isOnline, 0);
    }

    /**
     * 在对应位置添加车辆标志物
     *
     * @param latLng    位置信息
     * @param isOnline  车辆是否在线
     * @param direction 车辆方向
     * @return
     */
    private synchronized Marker addCarMarker(LatLng latLng, boolean isOnline, float direction) {
        // 创建标注物
        MarkerOptions markerOption = new MarkerOptions();
        // 设置地点位置（经纬度）
        markerOption.position(latLng);
        // 设置标注物的标题和描述--坑爹，必须设置
        markerOption.title("添加标注物").snippet("自定义标注物Window");
        // 设置标注物是否可以拖拽（长按拖拽）
        markerOption.draggable(true);
        //判断当前车辆方向
        carDirection = direction;
        boolean isRight = (direction >= 0 && direction <= 90) || (direction >= 270 && direction <= 360);
        // 设置标注物的自定义图标
        if (isOnline) {
            markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), isRight ? R.mipmap.motorcycle_right_online : R.mipmap.motorcycle_left_online)));//摩托车图标
        } else {
            markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), isRight ? R.mipmap.motorcycle_right_offline : R.mipmap.motorcycle_left_offline)));//摩托车图标
        }
        // 添加标注物至地图显示
        if (carMarker != null) {
            carMarker.remove();//清除上一个标志物
        }
        carMarker = aMap.addMarker(markerOption);
        return carMarker;
    }

    @Override
    public View getInfoWindow(Marker marker) {
        //判断如果是轨迹回放界面，则不显示车辆详情窗口
        if (fragmentType == TRACK_PLAY_BACK) return null;
        //判断是否是车辆标志物，不是则返回null
        if (!marker.equals(carMarker)) return null;
        View infoWindow = getActivity().getLayoutInflater().inflate(R.layout.dialog_info_window_gaode, null);
        //设备名称textView
        TextView name_textView = (TextView) infoWindow.findViewById(R.id.dialog_info_window_name_tv);

        //车辆速度LinearLayout   //车辆状态textview
        TextView carStatus_textview = (TextView) infoWindow.findViewById(R.id.dialog_info_window_car_status);
        LinearLayout speed_lingearLayout = (LinearLayout) infoWindow.findViewById(R.id.dialog_info_window_speed_ll);
        //速度textView
        TextView speed_textView = (TextView) infoWindow.findViewById(R.id.dialog_info_window_speed_tv);
        //ACC状态textView
        TextView accStatus_textView = (TextView) infoWindow.findViewById(R.id.dialog_info_window_acc_status_tv);
        //通信时间textView
        TextView communicationTime_textView = (TextView) infoWindow.findViewById(R.id.dialog_info_window_communication_time_tv);
        //定位时间textView
        TextView loactionTime_textView = (TextView) infoWindow.findViewById(R.id.dialog_info_window_loaction_time_tv);
        //设备详情button
        ImageButton carTerminalSetBtn = (ImageButton) infoWindow.findViewById(R.id.terminal_set_btn);
        carTerminalSetBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getActivity(), TerminalDetailsActivity.class);
                Bundle bundle = new Bundle();
                bundle.putInt(Constant.TerminalInfo.terminalId, terminalId);
                bundle.putString(Constant.FragmentInfo.fragment, Constant.FragmentInfo.carActivity);
                intent.putExtras(bundle);
                startActivityForResult(intent, 1);
            }
        });
        //是否在线textView
        TextView onlineStatus_textView = (TextView) infoWindow.findViewById(R.id.dialog_info_window_online_status);
        name_textView.setText(carListInfo.getDisplayid());
        //判断速度大小，若速度为0，则设置车辆状态为静止，不显示速度布局，否则显示为运动，显示车辆速度布局
        if (carListInfo.getSpeed() == 0) {
            speed_lingearLayout.setVisibility(View.GONE);
            carStatus_textview.setText(R.string.motionless);
        } else {
            speed_lingearLayout.setVisibility(carListInfo.getSpeed() == 10000 ? View.GONE : View.VISIBLE);//速度为10000则不显示，10000代表没有速度数据，但在运动
            String speed = carListInfo.getSpeed() + getResources().getString(R.string.km_h);
            speed_textView.setText(speed);
            carStatus_textview.setText(R.string.movement);
        }
        communicationTime_textView.setText(carListInfo.getUpdatedTime());
        loactionTime_textView.setText(carListInfo.getLocationTime());
        accStatus_textView.setText(carListInfo.getAcc() ? "开" : "关");
        onlineStatus_textView.setText(carListInfo.getOnline() ? "在线" : "离线");
        onlineStatus_textView.setTextColor(getResources().getColor(carListInfo.getOnline() ? R.color.green : R.color.orange));
        return infoWindow;
    }

    @Override
    public View getInfoContents(Marker marker) {
        return null;
    }

    public void updataCarInfo(MessageBean.TerminalStatusBean terminalStatusBean) {
        carListInfo.setOnline(terminalStatusBean.isOnline());
        carListInfo.setAcc(terminalStatusBean.isAcc());
        carListInfo.setUpdatedTime(terminalStatusBean.getUpdatedTime());
        carListInfo.setSpeed(terminalStatusBean.getSpeed());
        carMarker.showInfoWindow();
    }

    //*************************实时追踪界面对象和方法*************************//
    //实时追踪控制栏;
    private RelativeLayout realTimeTrackBar_rl;
    //刷新按钮
    private ImageButton refresh_button;
    //夜景地图
    private Button night_button;
    //实时路况
    private ImageButton traffic_button;
    //寻车导航
    private ImageButton carNaviFind_button;
    //位置切换button
    private ImageButton changePosition_button;
    //普通地图和卫星地图切换按钮
    private ImageButton mapType_button;
    //是否开启交通图
    private boolean trafficEnable = false;
    private ArrayList<LatLng> realLatLngList = new ArrayList<>();
    //路径线
    private PolylineOptions polylineOptions;
    //是否正在实时追踪
    public boolean isRealTimeTrack = true;
    //是否是车辆位置
    private boolean isCarPosition = false;
    //个人位置标志物
    private LatLng personalLatLng = null;

    /**
     * 设置是否显示交通图
     */
    public void setMapTraffic() {
        trafficEnable = !trafficEnable;
        aMap.setTrafficEnabled(trafficEnable);
        traffic_button.setSelected(trafficEnable);
    }

    /**
     * 绘制实时路径信息
     *
     * @param locationBean 最新的车辆位置信息
     */
    public synchronized void drawRealTimePath(MessageBean.LocationBean locationBean) {
        //判断当前是否定到位
        if (locationBean.getDw().equals("已定位")) {
            //高精度时不进行坐标判断，防止精度损失
            carLatLng = new LatLng(locationBean.getLatitude(), locationBean.getLongitude(), !isHighPrecision);
            //转换坐标形式
            carLatLng = GaoDeMapUtil.gaodeLatLngEncrypt(carLatLng);
            realLatLngList.add(carLatLng);
            if (realLatLngList.size() >= 2) {
                //上一个点的位置
                LatLng lastLatLng = realLatLngList.get(realLatLngList.size() - 2);
                //判断位置是否有变化
                if (lastLatLng.latitude == carLatLng.latitude && lastLatLng.longitude == carLatLng.longitude)
                    carListInfo.setSpeed(locationBean.getSpeed());
                else
                    //有就显示运动
                    carListInfo.setSpeed(locationBean.getSpeed() == 0 ? 10000 : locationBean.getSpeed());//如果有速度则设置相应的速度，没有则但是在运动则只显示状态为运动，根据速度为10000设置速度为不显示


            }
            //判断当前车辆方向
            float direction = locationBean.getDirection();
            //若方向变化大，则重新添加图标（分为左右两个方向两种图标）
            if (Math.abs(carDirection - direction) >= 180) {
                addCarMarker(carLatLng, true, locationBean.getDirection());
            }
            //设置移动动画
            Animation animationMove = new TranslateAnimation(carLatLng);
            long duration = 1000L;
            animationMove.setDuration(duration);
            carMarker.setAnimation(animationMove);

            carMarker.startAnimation();
            carMarker.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart() {
                }

                @Override
                public void onAnimationEnd() {
                    //动画结束后添加路径
                    polylineOptions.add(carLatLng);
                    aMap.addPolyline(polylineOptions);
                    // 移动到该位置
                    animateToLocation(carLatLng);
                }
            });
        }
        carListInfo.setAcc(locationBean.isAcc());
        carListInfo.setLocationTime(locationBean.getLocationTime());
        carListInfo.setUpdatedTime(locationBean.getUpdateTime());
        carMarker.showInfoWindow();
    }

    /**
     * 切换中心显示（人或者车辆）
     */
    public void changePosition() {
        isCarPosition = !isCarPosition;
        changePosition_button.setSelected(isCarPosition);
        //切换位置
        animateToLocation(isCarPosition ? carLatLng : personalLatLng);
    }

    /******************************
     * 定位监听
     ******************************/

    /**
     * 初始化定位服务
     */
    public void initLocation() {
        // 设置定位监听
        aMap.setLocationSource(this);
        // 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
        aMap.setMyLocationEnabled(true);
        // 设置定位的类型为定位模式，有定位、跟随或地图根据面向方向旋转几种
        aMap.setMyLocationType(AMap.LOCATION_TYPE_MAP_ROTATE);
    }

    private OnLocationChangedListener mListener;
    private AMapLocationClient mlocationClient;
    private AMapLocationClientOption mLocationOption;

    /**
     * 激活定位
     */
    @Override
    public void activate(OnLocationChangedListener onLocationChangedListener) {
        mListener = onLocationChangedListener;
        if (mlocationClient == null) {
            //初始化定位
            mlocationClient = new AMapLocationClient(getActivity());
            //初始化定位参数
            mLocationOption = new AMapLocationClientOption();
            //设置定位间隔,单位毫秒,默认为2000ms，最低1000ms。
            mLocationOption.setInterval(2000);
            //单位是毫秒，默认30000毫秒，建议超时时间不要低于8000毫秒。
            mLocationOption.setHttpTimeOut(20000);
            //设置为高精度定位模式
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            //设置定位参数
            mlocationClient.setLocationOption(mLocationOption);
            //设置定位回调监听
            mlocationClient.setLocationListener(this);
        }
    }

    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        //定位成功后回调函数
        if (mListener != null && aMapLocation != null) {
            if (aMapLocation != null && aMapLocation.getErrorCode() == 0) {
                //判断位置有无变化，没有则不更新位置标志物
                if (personalLatLng != null && personalLatLng.latitude == aMapLocation.getLatitude() && personalLatLng.longitude == aMapLocation.getLongitude()) {
                    return;
                }
                personalLatLng = new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude());
                personalMarker = aMap.addMarker(addPersonalMarker(aMapLocation));
            } else {
                String errText = "定位失败," + aMapLocation.getErrorCode() + ": " + aMapLocation.getErrorInfo();
                Log.e("AmapErr", errText);
            }
        }
    }

    private Marker personalMarker = null;

    /**
     * 往地图上添加当前定位marker
     *
     * @param amapLocation 位置信息
     */
    private MarkerOptions addPersonalMarker(AMapLocation amapLocation) {
        MarkerOptions markerOptions = new MarkerOptions();
        //如果标志物已经存在
        if (personalMarker != null) {
            //移除当前标志物
            personalMarker.remove();
        }
        markerOptions.position(new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude()));
        //图标
        markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ico_personal));
        markerOptions.title("[我的位置]");
        //设置多少帧刷新一次图片资源
        markerOptions.period(60);
        return markerOptions;
    }

    /**
     * 停止定位
     */
    @Override
    public void deactivate() {
        mListener = null;
        if (mlocationClient != null) {
            mlocationClient.stopLocation();
            mlocationClient.onDestroy();
        }
        mlocationClient = null;
    }

    //*************************轨迹回放界面方法*************************//
    //实时追踪控制栏;
    private LinearLayout playBackBar_ll;
    //普通地图
    private SeekBar playBack_seekBar;
    //回放button
    private Button playBack_button;
    //时间选择button
    private ImageButton timeChoice_button;
    //回放时车辆速度
    private TextView carSpeed_textview;
    //回放时定位时间
    private TextView carLocationTime_textview;
    //车辆经纬度
    private TextView carLongitude_textview;
    private TextView carLatitude_textview;
    //回放进度
    private TextView placBackProgress_textview;
    //存放所有路径点坐标信息的List
    private List<TerminalPathBean> terminalPathList;
    //修正后的轨迹list
    private List<LatLng> correctionPathList;
    //回放线程
    private Runnable playBackRunable = null;
    //轨迹纠偏按钮
    private FloatingActionButton trajectoryCorrection_button;


    private void setPathInfo(TerminalPathBean terminalPathBean) {
        setPathInfo(terminalPathBean, null);
    }

    /**
     * 根据路径点信息设置速度，定位时间，经纬度等信息的显示
     *
     * @param terminalPathBean 设备路径信息
     * @param newLatLng        其他坐标信息
     */
    private void setPathInfo(TerminalPathBean terminalPathBean, LatLng newLatLng) {
        String speed = getResources().getString(R.string.car_speed) + Float.toString(terminalPathBean.getSpeed()) + getResources().getString(R.string.km_h);
        //如果有其他坐标信息则替换
        if (newLatLng != null) {
            terminalPathBean.setLatitude(newLatLng.latitude);
            terminalPathBean.setLongitude(newLatLng.longitude);
        }
        final LatLng latlng = new LatLng(terminalPathBean.getLatitude(), terminalPathBean.getLongitude());
        String latitude = getResources().getString(R.string.latitude) + Double.toString(terminalPathBean.getLatitude()).trim();
        String longitude = getResources().getString(R.string.longitude) + Double.toString(terminalPathBean.getLongitude()).trim();
        //获得定位时间的 时分秒位
        String locationTime = getResources().getString(R.string.time) + terminalPathBean.getLocationTime().
                substring(terminalPathBean.getLocationTime().length() - 8,
                        terminalPathBean.getLocationTime().length());
        carSpeed_textview.setText(speed);
        carLatitude_textview.setText(latitude);
        carLongitude_textview.setText(longitude);
        carLocationTime_textview.setText(locationTime);
        placBackProgress_textview.setText(playBack_seekBar.getProgress() + "/" + playBack_seekBar.getMax());
        //判断当前车辆方向
        float direction = terminalPathBean.getDirection();
        //判断是否是拖动进度条，若为拖动进度条，则重新设置车辆标志物的位置，
        // 或者当车辆方向变化大，则重新添加图标（分为左右两个方向两种图标）
        if (isTouchProgress || Math.abs(carDirection - direction) >= 180) {
            addCarMarker(latlng, true, terminalPathBean.getDirection());
        } else {
            //设置移动动画
            Animation animationMove = new TranslateAnimation(latlng);
            long duration = 1000L;
            animationMove.setDuration(duration);
            carMarker.setAnimation(animationMove);
            carMarker.startAnimation();
            carMarker.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart() {

                }

                @Override
                public void onAnimationEnd() {
                    // 移动到该位置
                    animateToLocation(latlng);
                }
            });
        }
    }

    /**
     * 初始化轨迹（默认为当天轨迹）
     *
     * @param terminalId 设备Id
     * @param startTime  开始时间
     * @param endTime    结束时间
     */
    public void initPathToday(int terminalId, String startTime, String endTime) {
        //清除之前的轨迹
        terminalPathList = new ArrayList<>();
//        playBackPathList = new ArrayList<>();
        aMap.clear();

        //如果两个时间点时间超过30天，则不予查询
        if (TimeUtils.calculatingTimeDifferenceValue(startTime, endTime, TimeUtils.MINUTE_FORMAT_DATE) / 1440 > 30) {
            Toast.makeText(getActivity(), R.string.time_too_long, Toast.LENGTH_SHORT).show();
            return;
        }

        loadingDialog.setTextView(R.string.is_loading);
        presenter.queryLocationReplay(UrlAddress.QUERY_LOCATION_REPLAY, String.valueOf(terminalId), startTime, endTime, new BasePresenter.OnUIThreadListener<LocationReplayResult>() {
                    @Override
                    public void onBefore(Request request, int id) {
                        //如果正在回放，则暂停
                        if (isPlayBack) {
                            //停止回放线程
                            handler.removeCallbacks(playBackRunable);
                            isPlayBack = false;
                            playBack_button.setText(R.string.play_back);
                            return;
                        }
                        loadingDialog.show();
                    }

                    @Override
                    public void onAfter(int id) {
                    }

                    @Override
                    public void onError(Call call, Exception e, int i) {
                        loadingDialog.dismiss();
                        Toast.makeText(getActivity(), R.string.loading_fail, Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onResponse(LocationReplayResult result) {
                        switch (result.getStatus()) {
                            case "OK":
                                terminalPathList = result.getResult();
                                //回放路径中的坐标转换
                                terminalPathList = GaoDeMapUtil.gaodeTerminalPathListEncrypt(terminalPathList, isHighPrecision);
                                //将路径list倒叙排列，由于返回的路径信息为上传年时间早的在下
                                Collections.reverse(terminalPathList);
                                refreshPlayBackPath(terminalPathList);
                                //添加车辆在起点位置
                                LatLng latLng = new LatLng(terminalPathList.get(0).getLatitude(), terminalPathList.get(0).getLongitude());
                                addCarMarker(latLng, true, terminalPathList.get(0).getDirection());
                                break;
                            case "FAILED":
                                Toast.makeText(getActivity(), result.getMessage(), Toast.LENGTH_SHORT).show();
                                refreshPlayBackPath(new ArrayList<TerminalPathBean>());
                                playBack_button.setText(R.string.play_back);
                                carSpeed_textview.setText(R.string.speed);
                                carLatitude_textview.setText(R.string.latitude);
                                carLongitude_textview.setText(R.string.longitude);
                                carLocationTime_textview.setText(R.string.location_time);
                                break;
                        }
                        loadingDialog.dismiss();
                    }
                }

        );
        aMap.setMapType(AMap.MAP_TYPE_NORMAL);
        playBackRunable = new Runnable() {
            @Override
            public void run() {
                //获得当前进度
                int progress = playBack_seekBar.getProgress();
                if (progress != playBack_seekBar.getMax()) {
                    //设置进度
                    playBack_seekBar.setProgress(progress + 1);
                    //判断是否开启轨迹纠偏,设置相应的位置信息
                    if (trajectoryCorrection_button.isSelected()) {
                        //计算相对进度（由于轨迹纠正后路径点数量与未纠正时差别很大）
                        int relativeProgress = (progress * 100 / playBack_seekBar.getMax() * terminalPathList.size() / 100);
                        setPathInfo(terminalPathList.get(relativeProgress), correctionPathList.get(progress));
                    } else
                        setPathInfo(terminalPathList.get(progress));
                    handler.postDelayed(playBackRunable, 1000);//一秒一次执行，使得回放标志物移动
                    return;
                } else {
                    isPlayBack = false;
                    playBack_button.setText(R.string.play_back);
                    carSpeed_textview.setText(R.string.speed);
                    carLatitude_textview.setText(R.string.latitude);
                    carLongitude_textview.setText(R.string.longitude);
                    carLocationTime_textview.setText(R.string.location_time);
                }

            }
        };
    }

    /**
     * 刷新回放轨迹
     *
     * @param terminalPathList 回放路径点list
     */
    public void refreshPlayBackPath(List<TerminalPathBean> terminalPathList) {
        //按时间间隔将路线分为几条
        List<LatLng> pathList = dividingPath(terminalPathList);
        drawPathLine(pathList);
        //设置进度值
        playBack_seekBar.setProgress(0);
        //设置回放进度条最大值为路径点尺寸值
        playBack_seekBar.setMax(terminalPathList.size() - 1);
        //设定进度显示
        placBackProgress_textview.setText(0 + "/" + playBack_seekBar.getMax());
        placBackProgress_textview.setVisibility(playBack_seekBar.getMax() == 0 ? View.INVISIBLE : View.VISIBLE);
    }

    /**
     * 显示出对应路线List的路线
     *
     * @param list
     */
    private void drawPathLine(List<LatLng> list) {
        if (list == null || list.size() == 0) {
            return;
        }
        //开始画路线（多条路径时）
//        for (int i = 0; i < list.size(); i++) {
        //当前路线位置list
        List<LatLng> path = list;
        // 增加起点开始
        aMap.addMarker(new MarkerOptions()
                .position(path.get(0))
                .title("起点")
                .icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                        .decodeResource(
                                getResources(),
                                R.mipmap.nav_route_result_start_point))));
        // 增加路线
        PolylineOptions polylineOptions = (new PolylineOptions())
                .addAll(list)
                .color(Color.rgb(9, 129, 240)).width(4.0f);
        aMap.addPolyline(polylineOptions);
        //添加终点
        aMap.addMarker(new MarkerOptions()
                .position(path.get(path.size() - 1))
                .title("终点")
                .icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                        .decodeResource(
                                getResources(),
                                R.mipmap.nav_route_result_end_point))));
//        }
    }


    //是否正在滑动进度条
    private boolean isTouchProgress = false;

    //轨迹回放进度条方法
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        //正常回放不会触发,拖动时才会触发
        if (isTouchProgress && progress != 0 && progress <= playBack_seekBar.getMax()) {
            setPathInfo(terminalPathList.get(progress));
        }
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        //拖动进度条开始时，如果回放线程正在开始，暂停回放线程
        if (isPlayBack) {
            //停止回放线程
            handler.removeCallbacks(playBackRunable);
            return;
        }
        isTouchProgress = true;
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        //拖动进度条结束时，如果回放线程之前在开始，则继续开始
        if (isPlayBack) {
            //继续开始回放线程
            handler.post(playBackRunable);//执行回放线程
            return;
        }
        isTouchProgress = false;
    }


    //回放功能
    public void playBack() {
        //如果正在回放，则暂停
        if (isPlayBack) {
            //停止回放线程
            handler.removeCallbacks(playBackRunable);
            isPlayBack = false;
            playBack_button.setText(R.string.play_back);
            return;
        }
        //判断是否有回放路径
        if (playBack_seekBar.getMax() == 0 || terminalPathList.size() == 0) {
            Toast.makeText(getActivity(), R.string.no_playback_path, Toast.LENGTH_SHORT).show();
            return;
        }
        //判断当前回放位置，如果已经播放完毕则回到初始位置重新播放
        if (playBack_seekBar.getProgress() == playBack_seekBar.getMax() - 1) {
            playBack_seekBar.setProgress(0);
            //判断是否开启了轨迹纠偏
            if (trajectoryCorrection_button.isSelected()) {
                //获取路径第一个坐标
                LatLng latlng = new LatLng(correctionPathList.get(0).latitude, correctionPathList.get(0).longitude);
                addCarMarker(latlng, true);
            } else {
                //获取路径第一个坐标
                LatLng latlng = new LatLng(terminalPathList.get(0).getLatitude(), terminalPathList.get(0).getLongitude());
                addCarMarker(latlng, true, terminalPathList.get(0).getDirection());
            }
        }
        isPlayBack = true;
        playBack_button.setText(R.string.stop);
        handler.post(playBackRunable);//执行回放线程
    }

    //fragment显示与不显示时调用（切换时）
    @Override
    public void onHiddenChanged(boolean hidden) {
        //判断fragment是否正在轨迹回放中
        if (!hidden) {
            //fragment显示时
            if (isPlayBack) {
                isPlayBack = false;
                //停止回放线程
                handler.removeCallbacks(playBackRunable);
                playBack_button.setText(R.string.play_back);
                playBack_seekBar.setProgress(0);
                playBack_seekBar.setMax(0);
                //如果是实时追踪界面，则开启实时追踪
                isRealTimeTrack = fragmentType == REAL_TIME_TTACK;
            }
        } else {
            //fragment隐藏时
            mlocationClient.stopLocation();//取消定位服务
            //判断fragment是否正在实时追踪中
            if (isRealTimeTrack) {
                isRealTimeTrack = false;
            }
        }
        super.onHiddenChanged(hidden);
    }

    /**
     * 将路径点list按时间差（两路径点时间差>30分钟）分为多条路径
     *
     * @param terminalPathList 路径点list
     * @return
     */
    private List<LatLng> dividingPath(List<TerminalPathBean> terminalPathList) {
        if (terminalPathList == null || terminalPathList.size() == 0)
            return new ArrayList<>();
        //所有路线list
        List<List<LatLng>> pathList = new ArrayList<>();
        //当前路径
        List<LatLng> path = new ArrayList<>();
        //设定初始坐标
        TerminalPathBean terminalPathBean = terminalPathList.get(0);
        //初始点
        LatLng latlng = new LatLng(terminalPathBean.getLatitude(), terminalPathBean.getLongitude());
        LatLng latlngLater = new LatLng(terminalPathBean.getLatitude(), terminalPathBean.getLongitude());
        path.add(latlng);
        for (int i = 1; i < terminalPathList.size(); i++) {
            //判断当前路径点坐标是否正常，不正常则抛弃
            if (terminalPathList.get(i).getLatitude() == 0 || terminalPathList.get(i).getLongitude() == 0) {
                //移除该位置
                terminalPathList.remove(i);
                //由于移除，所以之后的对象下表向前移一位，所以下次循环时下标不变，所以执行i--
                i--;
                continue;
            }
            //这里时间为颠倒的，即上一个点的时间大于下一个点的时间
            //当前点时间
            String now = terminalPathList.get(i).getUpdateTime();
            //上一个点时间
            String later = terminalPathList.get(i - 1).getUpdateTime();
            /**
             * 暂时屏蔽，当前默认只有一条线
             */
            //判断时间差（分钟），大于30则判断为不同路线 ,时间差小于30分钟，则认为是同一条路线
//            if (TimeUtils.calculatingTimeDifferenceValue(later, now) > 30) {
//                //将上一个路线添加进路线集合
//                pathList.add(path);
//                //重新开启一个路线集合
//                path = new ArrayList<>();
//            }
            //将该位置添加进当前路线中
            terminalPathBean = terminalPathList.get(i);
            latlng = new LatLng(terminalPathBean.getLatitude(), terminalPathBean.getLongitude());
            path.add(latlng);
        }
        //将最后一条路径添加进路径list
        pathList.add(path);
        //计算坐标距离，显示不同地图缩放等级的地图
        //判断当前进度不是在最开始
        float distance = AMapUtils.calculateLineDistance(latlng, latlngLater);
        //根据总路线距离设定缩放大小
        zoomLevel = GaoDeMapUtil.getZoomLevelByDistance(distance);

        return path;
    }

    /**
     * 轨迹纠偏
     */
    public void trajectoryCorrection() {
        if (terminalPathList == null || terminalPathList.size() == 0) {
            Toast.makeText(getActivity(), R.string.no_trajectory_correction_path, Toast.LENGTH_SHORT).show();
            return;
        }
        //判断是否正在回放中
        if (isPlayBack) {
            isPlayBack = false;
            //停止回放线程
            handler.removeCallbacks(playBackRunable);
            playBack_button.setText(R.string.play_back);
            playBack_seekBar.setProgress(0);
            playBack_seekBar.setMax(0);
        }
        if (trajectoryCorrection_button.isSelected()) {
            //清除之前路线
            aMap.clear();
            trajectoryCorrection_button.setSelected(false);
            //如果纠偏已经开启，则关闭
            refreshPlayBackPath(terminalPathList);
            //添加车辆在起点位置
            LatLng latLng = new LatLng(terminalPathList.get(0).getLatitude(), terminalPathList.get(0).getLongitude());
            addCarMarker(latLng, true, terminalPathList.get(0).getDirection());
            return;
        }
        //待修正的轨迹List
        List<TraceLocation> pathList = new ArrayList<>();
        for (int i = 0; i < terminalPathList.size(); i++) {
            TraceLocation traceLocation = new TraceLocation();
            //设置位置信息
            traceLocation.setLatitude(terminalPathList.get(i).getLatitude());
            traceLocation.setLongitude(terminalPathList.get(i).getLongitude());
            traceLocation.setSpeed(terminalPathList.get(i).getSpeed());
            pathList.add(traceLocation);
        }
        //显示加载条
        loadingDialog.show();
        loadingDialog.setTextView(R.string.is_trajectory_correction);
        //第一个参数为路线ID（可多路径）,第二个为路径List,第三个为坐标类型，第四个为监听回调
        LBSTraceClient.getInstance(getActivity().getApplicationContext()).queryProcessedTrace(1, pathList, LBSTraceClient.TYPE_AMAP, new TraceListener() {
            @Override
            public void onRequestFailed(int i, String s) {
                //轨迹纠偏失败回调
                trajectoryCorrection_button.setSelected(false);
                loadingDialog.dismiss();
                Toast.makeText(getActivity(), R.string.trajectory_correction_fail, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onTraceProcessing(int i, int i1, List<LatLng> list) {
                //轨迹纠偏过程回调
            }

            @Override
            public void onFinished(int i, List<LatLng> list, int i1, int i2) {
                //清除之前路线
                aMap.clear();
                //轨迹纠偏结束回调
                //设置纠正后的轨迹List
                correctionPathList = list;
                drawPathLine(list);
                //设置进度值
                playBack_seekBar.setProgress(0);
                //设置回放进度条最大值为路径点尺寸值
                playBack_seekBar.setMax(list.size() - 1);
                //设定进度显示
                placBackProgress_textview.setText(0 + "/" + playBack_seekBar.getMax());
                placBackProgress_textview.setVisibility(playBack_seekBar.getMax() == 0 ? View.INVISIBLE : View.VISIBLE);
                //添加车辆在起点位置
                LatLng latLng = new LatLng(terminalPathList.get(0).getLatitude(), terminalPathList.get(0).getLongitude());
                addCarMarker(latLng, true, terminalPathList.get(0).getDirection());
                trajectoryCorrection_button.setSelected(true);
                loadingDialog.dismiss();
            }
        });
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        aMap.clear();
        if (null != mlocationClient) {
            mlocationClient.onDestroy();
        }
    }


}
